package cn.org.xiaosheng.resttemplate.utils;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.Map;

/**
 * @author XiaoSheng
 * @date 2023-11-19
 * @dec 描述
 */
@Component
public class PostUtils {

    @Resource
    private RestTemplate restTemplate;

    public static final String CONTENT_TYPE_JSON = "application/json;charset=utf-8";


    /**
     * post请求, 入参方式为form-data或者application/x-www-form-urlencoded方式
     * @param url 请求接口路径
     * @param params 请求接口参数集合
     * @param reqHeaders 请求头
     * @return
     */
    public JSONObject requestFormData(String url,
                                      MultiValueMap<String, String> params,
                                      Map<String, String> reqHeaders) {

        // 2.1 请求头设置,x-www-form-urlencoded格式的数据
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        if (CollUtil.isNotEmpty(reqHeaders)) {
            for (String key : headers.keySet()) {
                headers.set(key, reqHeaders.get(key).toString());
            }
        }
        // 2.3组装请求体
        HttpEntity<MultiValueMap<String, String>> body = new HttpEntity<>(params, headers);
        JSONObject jsonObject = restTemplate.postForObject(url, body, JSONObject.class);
        return jsonObject;
    }


    /**
     * post请求, 入参方式为form-data或者multipart/form-data方式, 文件上传
     * @param url 请求接口路径
     * @param params 请求接口参数集合
     * @param reqHeaders 请求头
     * @return
     */
    public JSONObject requestFormDataFile(String url,
                                      MultiValueMap<String, String> params,
                                      Map<String, String> reqHeaders) {

        // 2.1 请求头设置,multipart/form-data格式的数据
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        if (CollUtil.isNotEmpty(reqHeaders)) {
            for (String key : headers.keySet()) {
                headers.set(key, reqHeaders.get(key).toString());
            }
        }
        // 2.3组装请求体
        HttpEntity<MultiValueMap<String, String>> body = new HttpEntity<>(params, headers);
        JSONObject jsonObject = restTemplate.postForObject(url, body, JSONObject.class);
        return jsonObject;
    }


    /**
     * post请求, 入参方式为form-data或者application/x-www-form-urlencoded方式
     * @param url 请求接口路径
     * @param params 请求接口参数集合
     * @param reqHeaders 请求头
     * @return
     */
    public JSONObject requestFormDataBigFile(String url,
                                          MultiValueMap<String, String> params,
                                          Map<String, String> reqHeaders) {

        // 2.1 请求头设置,x-www-form-urlencoded格式的数据
        HttpHeaders headers = new HttpHeaders();
        headers.set("Content-Type", MediaType.APPLICATION_OCTET_STREAM_VALUE);
        headers.set("Content-Type", MediaType.ALL_VALUE);
        if (CollUtil.isNotEmpty(reqHeaders)) {
            for (String key : headers.keySet()) {
                headers.set(key, reqHeaders.get(key).toString());
            }
        }
        // 2.3组装请求体
        HttpEntity<MultiValueMap<String, String>> body = new HttpEntity<>(params, headers);
        JSONObject jsonObject = restTemplate.postForObject(url, body, JSONObject.class);
        return jsonObject;
    }

    /**
     * MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL
     *  通过POST请求调用第三方平台的API, 入参为JSON格式
     *
     * @param url 请求接口路径
     * @param params 请求接口参数集合
     * @return
     */
    public ResponseEntity<JSONObject> requestObject(String url,
                                                    Map<String, Object> params) {
        return requestObject(url, HttpMethod.POST, params, null);
    }

    /**
     * 通过POST请求调用第三方平台的API, 入参为JSON格式
     *
     * @param url  请求接口路径
     * @param method 可选
     * @param params 请求参数集合
     * @param headers 请求头
     * exchange方式适用于get, post请求, 需指定具体的请求方法(不可用!)
     * @return
     */
    public ResponseEntity<JSONObject> requestObject(String url,
                                                           HttpMethod method,
                                                           Map<String, Object> params,
                                                           Map<String, Object> headers) {
        // 1. 设置请求头
        HttpHeaders httpHeaders = new HttpHeaders();
        if (CollUtil.isNotEmpty(headers)) {
            for (String key : headers.keySet()) {
                httpHeaders.set(key, headers.get(key).toString());
            }
        } else {
            httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        }
        HttpEntity<Object> entity = new HttpEntity<>(httpHeaders);
        ResponseEntity<JSONObject> exchange = restTemplate.exchange(url, method, entity, JSONObject.class, params);
        return exchange;
    }

    /**
     * 通过post请求调用第三方平台的API
     *
     * @param url     请求接口路径
     * @param headers 请求头参数集合
     * @param body    请求参数集合
     * @return
     */
    public ResponseEntity<JSONObject> postRequest(String url,
                                                         Map<String, Object> headers,
                                                         Map<String, Object> body) {
        RestTemplate restTemplate = new RestTemplate();
        //创建请求头
        HttpHeaders httpHeaders = new HttpHeaders();
        if (CollUtil.isNotEmpty(headers)) {
            // 遍历headers集合, 将所有头对象封装到请求中
            for (Map.Entry<String, Object> stringObjectEntry : headers.entrySet()) {
                httpHeaders.add(stringObjectEntry.getKey(), stringObjectEntry.getValue().toString());
            }
        }
        // 默认请求传输文件方式是json格式
        httpHeaders.add(HttpHeaders.CONTENT_TYPE, CONTENT_TYPE_JSON);
        //创建请求体并添加数据
        HttpEntity<String> httpEntity = new HttpEntity<String>(JSONObject.toJSONString(body), httpHeaders);
        //此处三个参数分别是请求地址、请求体以及返回参数类型
        ResponseEntity<JSONObject> forEntity = restTemplate.postForEntity(url, httpEntity, JSONObject.class);
        return forEntity;
    }

}
